﻿namespace Typps
{
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.IO;
    using System.Text;
    using System.Text.RegularExpressions;

    public class HttpFormatFilter : Stream
    {
        #region Fields

        HtmlFormatter hf;
        private Stream stream;

        #endregion Fields

        #region Constructors

        public HttpFormatFilter(Stream stm, List<string> elementsToIgnore, bool removeWhiteSpace)
            : this(stm, string.Empty, elementsToIgnore, true, null, null,removeWhiteSpace)
        {
        }

        public HttpFormatFilter(Stream stm, string tab, List<string> elementsToIgnore,bool removeWhiteSpace)
            : this(stm, tab, elementsToIgnore, false, null, null, removeWhiteSpace)
        {
        }

        public HttpFormatFilter(Stream stm, string tab, bool concatScriptBlocks, bool removeWhiteSpace)
            : this(stm, tab, null, concatScriptBlocks, null, null, removeWhiteSpace)
        {
        }

        public HttpFormatFilter(Stream stm, string tab, List<string> elementsToIgnore, bool concatScriptBlocks, List<string> scriptIgnoreList, bool removeWhiteSpace)
            : this(stm, tab, elementsToIgnore, concatScriptBlocks, scriptIgnoreList, null, false)
        {
        }

        public HttpFormatFilter(Stream stm, string tab, List<string> elementsToIgnore, bool concatScriptBlocks, List<string> scriptIgnoreList, List<string> noFormattingList, bool removeWhiteSpace)
        {
            stream = stm;
            hf = new HtmlFormatter(tab, elementsToIgnore, concatScriptBlocks, scriptIgnoreList, noFormattingList);
            hf.RemoveFormattingAndSpaces = removeWhiteSpace;
        }

        #endregion Constructors

        #region Properties

        public override bool CanRead
        {
            get { return false; }
        }

        public override bool CanSeek
        {
            get { return false; }
        }

        public override bool CanWrite
        {
            get { return true; }
        }

        public override long Length
        {
            get { throw new NotSupportedException(); }
        }

        public override long Position
        {
            get { throw new NotSupportedException(); }
            set { throw new NotSupportedException(); }
        }

        #endregion Properties

        #region Methods

        public override void Flush()
        {
            stream.Flush();
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            throw new NotSupportedException();
        }

        public override long Seek(long offset, SeekOrigin origin)
        {
            throw new NotSupportedException();
        }

        public override void SetLength(long value)
        {
            throw new NotSupportedException();
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            Decoder dec = Encoding.UTF8.GetDecoder();
            int charCount = dec.GetCharCount(buffer, offset, count);
            char[] result = new char[charCount];
            int decodedCharCount = dec.GetChars(buffer, offset, count, result, 0);

            if (decodedCharCount <= 0)
                return;

            byte[] transformedBuffer = Encoding.UTF8.GetBytes(hf.Parse(result));
            if (transformedBuffer.Length == 0) return;
            stream.Write(transformedBuffer, offset, transformedBuffer.Length);
        }

        #endregion Methods
    }
}